/* 
 * File:   BlockGroup.cpp
 * Author: chris
 *
 * Created on January 26, 2009, 8:26 PM
 */

/*
 * Created on February 2, 2008.
 *
 * Modifed: CGP; 1/26/09; Converted from Java to C++.
 */

#include "FSBlock.h"
#include "BlockLinkedList.h"
#include "BlockGroupException.h"
#include "BlockGroup.h"
#include "FreeList.h"


BlockGroup::BlockGroup(BlockLinkedList *bll) : BlockLinkedList(bll) {
}


BlockGroup::BlockGroup(unsigned int startBlock, unsigned int endBlock, 
        unsigned int numberOfBlocks, BlockLinkedList *motherFreeList)
        : BlockLinkedList(motherFreeList) {

    if ((startBlock == 0) || (startBlock >= m_disk->numberOfBlocks()) ||
            (endBlock == 0) || (endBlock >= m_disk->numberOfBlocks()) ||
            (numberOfBlocks <= 0) || (numberOfBlocks >= m_disk->numberOfBlocks())) {
        printf("BlockGroup: ERROR: Could not create BlockGroup\n");
        throw BlockGroupException();
    }

    m_startBlockNumber = startBlock;
    m_endBlockNumber = endBlock;
    m_numberOfBlocks = numberOfBlocks;
    m_motherFreeList = motherFreeList;

    unsigned int cnt = CountBlocks(FreeList::DEFAULT_NUMBER_OF_BLOCKS);
    Rewind(); // because CountBlocks() changes the Rewind state of the BlockGroup

    if (cnt != m_numberOfBlocks) {
        printf("BlockGroup: CountBlocks()= %d is not the same as m_numberOfBlocks= %d\n",
                cnt, m_numberOfBlocks);
        throw BlockGroupException();
    }
}


bool BlockGroup::AddBlock() {

    FSBlock *blk = NULL;

    if (m_motherFreeList != NULL) {
        blk = m_motherFreeList->UnlinkBlock(
                );
    } else {
        printf("BlockGroup.AddBlock: ERROR: FreeList BlockGroup was null.\n");
        return false;
    }

    BlockLinkedList::AddBlock(blk);
    delete blk;

    return true;
}

void BlockGroup::SetFreeList(BlockLinkedList *motherFreeList) {
	m_motherFreeList = motherFreeList;
}



